{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 迁移VGG16"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torchvision\n",
    "from torchvision import datasets, models, transforms\n",
    "import os\n",
    "from torch.autograd import Variable\n",
    "import matplotlib.pyplot as plt\n",
    "import time\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "ename": "IndentationError",
     "evalue": "unexpected indent (<ipython-input-2-e3a6ab682ada>, line 17)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-2-e3a6ab682ada>\"\u001b[0;36m, line \u001b[0;32m17\u001b[0m\n\u001b[0;31m    X_example, y_example = next(iter(dataloader[\"train\"]))\u001b[0m\n\u001b[0m    ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m unexpected indent\n"
     ]
    }
   ],
   "source": [
    "data_dir = \"DogsVSCats\"\n",
    "data_transform = {x:transforms.Compose([transforms.Scale([224,224]),\n",
    "                                        transforms.ToTensor(),\n",
    "                                        transforms.Normalize(mean=[0.5,0.5,0.5], std=[0.5,0.5,0.5])])\n",
    "                  for x in [\"train\", \"valid\"]}\n",
    "\n",
    "image_datasets = {x:datasets.ImageFolder(root = os.path.join(data_dir,x),\n",
    "                                         transform = data_transform[x])\n",
    "                  for x in [\"train\", \"valid\"]}\n",
    "\n",
    "dataloader = {x:torch.utils.data.DataLoader(dataset= image_datasets[x],\n",
    "                                            batch_size = 16,\n",
    "                                            shuffle = True)\n",
    "\n",
    "              \n",
    "for x in [\"train\", \"valid\"]}\n",
    "    X_example, y_example = next(iter(dataloader[\"train\"]))\n",
    "    example_clasees = image_datasets[\"train\"].classes\n",
    "    index_classes = image_datasets[\"train\"].class_to_idx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = models.vgg16(pretrained=True)\n",
    "Use_gpu = torch.cuda.is_available()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for parma in model.parameters():\n",
    "    parma.requires_grad = False\n",
    "    model.classifier = torch.nn.Sequential(torch.nn.Linear(25088, 4096),\n",
    "                                           torch.nn.ReLU(),\n",
    "                                           torch.nn.Dropout(p=0.5),\n",
    "                                           torch.nn.Linear(4096, 4096),\n",
    "                                           torch.nn.ReLU(),\n",
    "                                           torch.nn.Dropout(p=0.5),\n",
    "                                           torch.nn.Linear(4096, 2))\n",
    "if Use_gpu:\n",
    "    model = model.cuda()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cost = torch.nn.CrossEntropyLoss()\n",
    "optimizer = torch.optim.Adam(model.classifier.parameters())\n",
    "loss_f = torch.nn.CrossEntropyLoss()\n",
    "optimizer = torch.optim.Adam(model.classifier.parameters(), lr = 0.00001)\n",
    "epoch_n = 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "time_open = time.time()\n",
    "for epoch in range(epoch_n):\n",
    "    print(\"Epoch {}/{}\".format(epoch, epoch_n - 1))\n",
    "    print(\"-\"*10)\n",
    "    for phase in [\"train\", \"valid\"]:\n",
    "        if phase == \"train\":\n",
    "            print(\"Training...\")\n",
    "            model.train(True)\n",
    "        else:\n",
    "            print(\"Validing...\")\n",
    "            model.train(False)\n",
    "            \n",
    "    running_loss = 0.0\n",
    "    running_corrects = 0\n",
    "    for batch, data in enumerate(dataloader[phase], 1):\n",
    "\n",
    "        X, y = data\n",
    "        if Use_gpu:\n",
    "            X, y = Variable(X.cuda()), Variable(y.cuda())\n",
    "        else:\n",
    "            X, y = Variable(X), Variable(y)\n",
    "            \n",
    "        y_pred = model(X)\n",
    "        _, pred = torch.max(y_pred.data, 1)\n",
    "        optimizer.zero_grad()\n",
    "        loss = loss_f(y_pred, y)\n",
    "        \n",
    "        if phase == \"train\":\n",
    "            loss.backward()\n",
    "            optimizer.step()\n",
    "            running_loss += loss.data[0]\n",
    "            running_corrects += torch.sum(pred == y.data)\n",
    "            \n",
    "            if batch%500 == 0 and phase ==\"train\":\n",
    "                print(\"Batch {}, Train Loss:{:.4f}, Train ACC:{:.4f}\".format(batch, running_loss/batch, 100*running_corrects(16*batch)))\n",
    "\n",
    "    epoch_loss = running_loss*16/len(image_datasets[phase])\n",
    "    epoch_acc = 100*running_corrects/len(image_datasets[phase])\n",
    "    print(\"{} Loss:{:.4f} Acc:{:.4f}%\".format(phase, epoch_loss,epoch_acc))\n",
    "            \n",
    "time_end = time.time() - time_open\n",
    "print(time_end)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 迁移ResNet50"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torchvision\n",
    "from torchvision import datasets, models, transforms\n",
    "import os\n",
    "from torch.autograd import Variable\n",
    "import matplotlib.pyplot as plt\n",
    "import time\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "path = \"dog_vs_cat\"\n",
    "transform = transforms.Compose([transforms.CenterCrop(224),\n",
    "                                transforms.ToTensor(),\n",
    "                                transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])])\n",
    "\n",
    "data_dir = \"DogsVSCats\"\n",
    "data_transform = {x:transforms.Compose([transforms.Scale([224,224]),\n",
    "                                        transforms.ToTensor(),\n",
    "                                        transforms.Normalize(mean=[0.5,0.5,0.5], std=[0.5,0.5,0.5])])\n",
    "                  for x in [\"train\", \"valid\"]}\n",
    "\n",
    "image_datasets = {x:datasets.ImageFolder(root = os.path.join(data_dir,x),\n",
    "                                         transform = data_transform[x])\n",
    "                  for x in [\"train\", \"valid\"]}\n",
    "\n",
    "dataloader = {x:torch.utils.data.DataLoader(dataset= image_datasets[x],\n",
    "                                            batch_size = 16,\n",
    "                                            shuffle = True)\n",
    "              for x in [\"train\", \"valid\"]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for parma in model.parameters():\n",
    "    parma.requires_grad = False\n",
    "    model.fc = torch.nn.Linear(2048, 2)\n",
    "    \n",
    "if Use_gpu:\n",
    "    model = model.cuda()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cost = torch.nn.CrossEntropyLoss()\n",
    "optimizer = torch.optim.Adam(model.fc.parameters())\n",
    "\n",
    "loss_f = torch.nn.CrossEntropyLoss()\n",
    "optimizer = torch.optim.Adam(model.fc.parameters(), lr = 0.00001)\n",
    "epoch_n = 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "time_open = time.time()\n",
    "for epoch in range(epoch_n):\n",
    "    print(\"Epoch {}/{}\".format(epoch, epoch_n - 1))\n",
    "    print(\"-\"*10)\n",
    "    \n",
    "    for phase in [\"train\", \"valid\"]:\n",
    "        if phase == \"train\":\n",
    "            print(\"Training...\")\n",
    "            model.train(True)\n",
    "        else:\n",
    "            print(\"Validing...\")\n",
    "            model.train(False)\n",
    "            \n",
    "        running_loss = 0.0\n",
    "        running_corrects = 0\n",
    "        \n",
    "        for batch, data in enumerate(dataloader[phase], 1):\n",
    "            X, y = data\n",
    "            if Use_gpu:\n",
    "                X, y = Variable(X.cuda()), Variable(y.cuda())\n",
    "            else:\n",
    "                X, y = Variable(X), Variable(y)\n",
    "            y_pred = model(X)\n",
    "            _, pred = torch.max(y_pred.data, 1)\n",
    "            optimizer.zero_grad()\n",
    "            loss = loss_f(y_pred, y)\n",
    "            if phase == \"train\":\n",
    "                loss.backward()\n",
    "                optimizer.step()\n",
    "                running_loss += loss.data[0]\n",
    "                running_corrects += torch.sum(pred == y.data)\n",
    "                if batch%500 == 0 and phase ==\"train\":\n",
    "                    print(\"Batch {}, Train Loss:{:.4f}, Train ACC:{:.4f}\".format(batch, running_loss/batch,100*running_corrects/(16*batch)))\n",
    "            \n",
    "        epoch_loss = running_loss*16/len(image_datasets[phase])\n",
    "        epoch_acc = 100*running_corrects/len(image_datasets[phase])\n",
    "        print(\"{} Loss:{:.4f} Acc:{:.4f}%\".format(phase, epoch_loss,epoch_acc))\n",
    "            \n",
    "time_end = time.time() - time_open\n",
    "print(time_end)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
